<template>
  <div class="extraction-container">
    <h1>威胁情报提取</h1>
    
    <div class="extraction-form">
      <div class="form-group">
        <label for="extraction-title">标题 (可选)</label>
        <input 
          type="text" 
          id="extraction-title" 
          v-model="title" 
          placeholder="为这次提取命名"
          class="form-control"
        />
      </div>
      
      <div class="form-group">
        <label for="extraction-text">非结构化文本</label>
        <textarea 
          id="extraction-text" 
          v-model="text" 
          placeholder="粘贴或输入包含威胁情报的非结构化文本..."
          class="form-control"
          rows="12"
        ></textarea>
      </div>
      
      <div class="actions">
        <button 
          @click="extractIntelligence" 
          :disabled="!text || loading" 
          class="btn-primary"
        >
          {{ loading ? '提取中...' : '提取威胁情报' }}
        </button>
        <button 
          @click="clearForm" 
          :disabled="loading" 
          class="btn-secondary"
        >
          清空
        </button>
      </div>
    </div>
    
    <div v-if="loading" class="loading-indicator">
      <div class="spinner"></div>
      <div>正在提取威胁情报，这可能需要一些时间...</div>
    </div>
    
    <div v-if="result && result.success" class="result-container success">
      <h3>提取成功</h3>
      <p>{{ result.message }}</p>
      <div class="actions">
        <router-link to="/graph" class="btn-primary">查看知识图谱</router-link>
      </div>
    </div>
    
    <div v-if="result && !result.success" class="result-container error">
      <h3>提取失败</h3>
      <p>{{ result.error }}</p>
    </div>
    
    <div class="stats-container" v-if="stats">
      <h2>知识图谱统计</h2>
      
      <div class="stats-grid">
        <div class="stats-card">
          <h3>实体类型统计</h3>
          <div class="stats-chart">
            <canvas ref="entityChart" width="300" height="200"></canvas>
          </div>
          <div class="stats-list">
            <div v-for="(count, type) in stats.entity_stats" :key="type" class="stats-item">
              <span class="type">{{ type }}</span>
              <span class="count">{{ count }}</span>
            </div>
          </div>
        </div>
        
        <div class="stats-card">
          <h3>关系类型统计</h3>
          <div class="stats-chart">
            <canvas ref="relationshipChart" width="300" height="200"></canvas>
          </div>
          <div class="stats-list">
            <div v-for="(count, type) in stats.relationship_stats" :key="type" class="stats-item">
              <span class="type">{{ type }}</span>
              <span class="count">{{ count }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios';
import Chart from 'chart.js/auto';

export default {
  name: 'TextExtractionView',
  data() {
    return {
      title: '',
      text: '',
      loading: false,
      result: null,
      stats: null,
      entityChart: null,
      relationshipChart: null,
      colors: [
        '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', 
        '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', 
        '#bcbd22', '#17becf', '#aec7e8', '#ffbb78'
      ]
    };
  },
  mounted() {
    this.fetchStats();
  },
  methods: {
    async extractIntelligence() {
      if (!this.text) return;
      
      this.loading = true;
      this.result = null;
      
      try {
        const token = localStorage.getItem('token');
        if (!token) {
          this.$router.push('/login');
          return;
        }
        
        const response = await axios.post(
          'http://localhost:8000/extract',
          {
            text: this.text,
            title: this.title || undefined
          },
          {
            headers: {
              'Authorization': `Bearer ${token}`
            }
          }
        );
        
        this.result = response.data;
        
        // After successful extraction, refresh stats
        if (this.result.success) {
          await this.fetchStats();
        }
      } catch (error) {
        console.error('Error extracting intelligence:', error);
        this.result = {
          success: false,
          error: error.response?.data?.error || '提取过程中发生错误，请稍后再试。'
        };
      } finally {
        this.loading = false;
      }
    },
    
    clearForm() {
      this.title = '';
      this.text = '';
      this.result = null;
    },
    
    async fetchStats() {
      try {
        const token = localStorage.getItem('token');
        if (!token) return;
        
        const response = await axios.get(
          'http://localhost:8000/extract/stats',
          {
            headers: {
              'Authorization': `Bearer ${token}`
            }
          }
        );
        
        if (response.data.success) {
          this.stats = response.data;
          this.$nextTick(() => {
            this.renderCharts();
          });
        }
      } catch (error) {
        console.error('Error fetching stats:', error);
      }
    },
    
    renderCharts() {
      if (!this.stats) return;
      
      // Clean up existing charts
      if (this.entityChart) {
        this.entityChart.destroy();
      }
      
      if (this.relationshipChart) {
        this.relationshipChart.destroy();
      }
      
      // Prepare entity chart data
      const entityStats = this.stats.entity_stats;
      const entityLabels = Object.keys(entityStats);
      const entityData = Object.values(entityStats);
      
      // Render entity chart
      const entityCtx = this.$refs.entityChart.getContext('2d');
      this.entityChart = new Chart(entityCtx, {
        type: 'pie',
        data: {
          labels: entityLabels,
          datasets: [{
            data: entityData,
            backgroundColor: entityLabels.map((_, i) => this.colors[i % this.colors.length]),
            borderWidth: 1
          }]
        },
        options: {
          responsive: true,
          plugins: {
            legend: {
              position: 'right',
              labels: {
                boxWidth: 12,
                font: {
                  size: 10
                }
              }
            }
          }
        }
      });
      
      // Prepare relationship chart data
      const relationshipStats = this.stats.relationship_stats;
      const relationshipLabels = Object.keys(relationshipStats);
      const relationshipData = Object.values(relationshipStats);
      
      // Render relationship chart
      const relationshipCtx = this.$refs.relationshipChart.getContext('2d');
      this.relationshipChart = new Chart(relationshipCtx, {
        type: 'bar',
        data: {
          labels: relationshipLabels,
          datasets: [{
            label: '关系数量',
            data: relationshipData,
            backgroundColor: relationshipLabels.map((_, i) => this.colors[i % this.colors.length]),
            borderWidth: 1
          }]
        },
        options: {
          responsive: true,
          plugins: {
            legend: {
              display: false
            }
          },
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }
  }
};
</script>

<style scoped>
.extraction-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

h1 {
  color: #333;
  margin-bottom: 30px;
}

.extraction-form {
  background-color: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 600;
  color: #333;
}

.form-control {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

textarea.form-control {
  resize: vertical;
}

.actions {
  display: flex;
  gap: 10px;
  margin-top: 15px;
}

.btn-primary {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
}

.btn-primary:hover {
  background-color: #0056b3;
}

.btn-primary:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.btn-secondary {
  background-color: #6c757d;
  color: white;
  border: none;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
}

.btn-secondary:hover {
  background-color: #5a6268;
}

.btn-secondary:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.loading-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 30px 0;
}

.spinner {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 3px solid #f3f3f3;
  border-top-color: #007bff;
  animation: spin 1s linear infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.result-container {
  margin-top: 20px;
  padding: 15px;
  border-radius: 6px;
}

.result-container.success {
  background-color: #d4edda;
  border: 1px solid #c3e6cb;
  color: #155724;
}

.result-container.error {
  background-color: #f8d7da;
  border: 1px solid #f5c6cb;
  color: #721c24;
}

.result-container h3 {
  margin-top: 0;
  margin-bottom: 10px;
}

.stats-container {
  margin-top: 30px;
}

.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 20px;
}

@media (max-width: 768px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }
}

.stats-card {
  background-color: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.stats-card h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #333;
}

.stats-chart {
  margin-bottom: 15px;
  height: 200px;
}

.stats-list {
  max-height: 200px;
  overflow-y: auto;
  border-top: 1px solid #eee;
  padding-top: 10px;
}

.stats-item {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px solid #f0f0f0;
}

.stats-item .type {
  font-weight: 600;
}

.stats-item .count {
  color: #007bff;
  font-weight: 600;
}
</style> 